/**
 * 
 */
package edu.umd.clip.lm.questions;

import org.w3c.dom.*;

import edu.umd.clip.lm.model.AbstractProbTree;
import edu.umd.clip.lm.model.data.Context;
import edu.umd.clip.lm.util.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class AndQuestion extends Question {
	private Question question1;
	private Question question2;
	
	public AndQuestion(Question q1, Question q2) {
		super((byte)0, q1.aboutHidden || q2.aboutHidden);
		assert(!(q1.aboutHidden && q2.aboutHidden));
		question1 = q1;
		question2 = q2;
	}
	
	/**
	 * @param xmlnode
	 */
	public AndQuestion(Element xmlnode) {
		super(xmlnode);
		NodeList nodes = XMLUtils.getChildrenElementsByTagName(xmlnode, Question.XML_ELEMENT_NAME);
		assert(nodes.getLength() == 2);
		question1 = Question.fromXML((Element) nodes.item(0));
		question2 = Question.fromXML((Element) nodes.item(1));
	}

	public static Question fromXML(Element xmlnode) {
		AndQuestion q = new AndQuestion(xmlnode);
		return q;
	}
	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#implication(edu.umd.clip.lm.questions.Question, boolean)
	 */
	@Override
	public Boolean implication(Question q, boolean value) {
		Boolean res1 = question1.implication(q, value);
		if (res1 == null) return null;
		if (res1.booleanValue() == false) return res1;
		return question2.implication(q, value);
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#test(edu.umd.clip.lm.model.training.Context)
	 */
	@Override
	public boolean test(Context ctx) {
		return question1.test(ctx) && question2.test(ctx);
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#test(java.util.AbstractList)
	 */
	@Override
	public TestResult test(AbstractProbTree[] context) {
		TestResult res1 = question1.test(context);
		if (!res1.isSplit() && res1.getResult() == false) return res1;
		TestResult res2 = question2.test(context);
		if (res2.isSplit() || res2.getResult() == false) return res2;
		return res1;
	}
	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#createXML(org.w3c.dom.Document)
	 */
	@Override
	public Element createXML(Document doc) {
		Element elem = super.createXML(doc);
		elem.appendChild(question1.createXML(doc));
		elem.appendChild(question2.createXML(doc));
		return elem;
	}
	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#toShortString()
	 */
	@Override
	public String toShortString() {
		
		return '[' + question1.toShortString() + " AND " + question2.toShortString() + ']';
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return '[' + question1.toString() + " AND " + question2.toString() + ']';
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#getQuestionType()
	 */
	@Override
	public int getQuestionType() {
		return AND_QUESTION;
	}

	/* (non-Javadoc)
	 * @see edu.umd.clip.lm.questions.Question#test(edu.umd.clip.lm.model.AbstractProbTree)
	 */
	@Override
	public TestResult test(AbstractProbTree item) {
		assert(question1.timeOffset == question2.timeOffset);
		
		TestResult res1 = question1.test(item);
		if (!res1.isSplit() && res1.getResult() == false) return res1;
		TestResult res2 = question2.test(item);
		if (res2.isSplit() || res2.getResult() == false) return res2;
		return res1;
	}

}
